package com.hyd.manage.controller;

import java.math.BigDecimal;
import java.util.*;
import java.time.LocalDate;
import java.time.ZoneId;
import javax.servlet.http.HttpServletResponse;

import com.hyd.common.utils.DateUtils;
import com.hyd.manage.domain.Medicines;
import com.hyd.manage.domain.Sales;
import com.hyd.manage.domain.vo.*;
import com.hyd.manage.service.IMedicinesService;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.hyd.common.annotation.Log;
import com.hyd.common.core.controller.BaseController;
import com.hyd.common.core.domain.AjaxResult;
import com.hyd.common.enums.BusinessType;
import com.hyd.manage.domain.SalesRecord;
import com.hyd.manage.service.ISalesRecordService;
import com.hyd.common.utils.poi.ExcelUtil;
    import com.hyd.common.core.page.TableDataInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 药品销售记录Controller
 *
 * @author hwb
 * @date 2025-02-20
 */
@Api(tags = "药品销售记录Controller")
@RestController
@RequestMapping("/manage/record")
public class SalesRecordController extends BaseController
{
    @Autowired
    private ISalesRecordService salesRecordService;
    @Autowired
    private IMedicinesService medicinesService;

    /**
     * 获取当天的销售额和毛利润
     */
    @ApiOperation("获取当天的销售额和毛利润")
    @GetMapping("/TodaySalesVolume")
    public TodayVolumeVo getTodaySalesVolume() {
        List<SalesRecord> salesRecordList = salesRecordService.selectSalesRecordListByStatus(null);
        TodayVolumeVo todayVolumeVo = new TodayVolumeVo();
        todayVolumeVo.setSaleVolume(BigDecimal.ZERO);
        todayVolumeVo.setGrossProfit(BigDecimal.ZERO);
        for (SalesRecord salesRecord : salesRecordList) {
            LocalDate saleDate = salesRecord.getSaleDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate voDate = DateUtils.getNowDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            // 判断销售时间是否是今天
            if (saleDate.equals(voDate)) {
                // 设置销售额
                todayVolumeVo.setSaleVolume(todayVolumeVo.getSaleVolume().add(salesRecord.getTotalAmount()));
                // 通过药品编码和批次号获取药品信息
                Medicines medicine = medicinesService.selectMedicineByCodeAndNumber(salesRecord.getMedicineCode(), salesRecord.getBatchNumber());
                // 获得药品进价和销售价格
                BigDecimal purchasePrice = medicine.getPurchasePrice();
                BigDecimal salePrice = salesRecord.getSalePrice();
                // 获得药品销售数量
                Long quantity = salesRecord.getQuantity();
                // 获得毛利润
                BigDecimal grossProfit = salePrice.subtract(purchasePrice).multiply(new BigDecimal(quantity));
                // 设置毛利润
                todayVolumeVo.setGrossProfit(todayVolumeVo.getGrossProfit().add(grossProfit));
            }
        }
        return todayVolumeVo;
    }

    /**
     * 获取一周内每个药品的销售额
     */
    @ApiOperation("获取一周内每个药品的销售额")
    @GetMapping("/DrugVolume")
    public List<DrugVolumeVo> getDrugVolume() {
        List<SalesRecord> salesRecordList = salesRecordService.selectSalesRecordListByStatus(null);
        Map<String, DrugVolumeVo> drugVolumeMap = new HashMap<>();
        // 获取本地时间
        Date nowDate = DateUtils.getNowDate();
        // 计算7天前的时间
        Date sevenDaysAgo = new Date(nowDate.getTime() - 7L * 24 * 60 * 60 * 1000);
        for (SalesRecord salesRecord : salesRecordList) {
            Date saleDate = salesRecord.getSaleDate();
            String medicineName = salesRecord.getMedicineName();
            // 空值检查
            if (saleDate == null || medicineName == null) {
                continue;
            }
            // 判断销售时间是否在7天内
            if (saleDate.after(sevenDaysAgo)) {
                // 检查药品是否已存在于 Map 中
                if (drugVolumeMap.containsKey(medicineName)) {
                    // 如果存在，则更新销售量
                    DrugVolumeVo drugVolumeVo = drugVolumeMap.get(medicineName);
                    drugVolumeVo.setSaleVolume(drugVolumeVo.getSaleVolume().add(salesRecord.getTotalAmount()));
                } else {
                    // 如果不存在，则创建新的 DrugVolumeVo 对象并添加到 Map 中
                    DrugVolumeVo drugVolumeVo = new DrugVolumeVo();
                    drugVolumeVo.setMedicineName(medicineName);
                    drugVolumeVo.setSaleVolume(salesRecord.getTotalAmount());
                    drugVolumeMap.put(medicineName, drugVolumeVo);
                }
            }
        }
        // 保留销售额前9的数据，其他数据归类为其他
        // 将 Map 中的值转换为 List 并按销售额降序排序
        List<DrugVolumeVo> drugVolumeList = new ArrayList<>(drugVolumeMap.values());
        drugVolumeList.sort((a, b) -> b.getSaleVolume().compareTo(a.getSaleVolume()));

        // 保留前9名，其余归类为“其他”
        List<DrugVolumeVo> top9List = new ArrayList<>();
        BigDecimal otherTotalAmount = BigDecimal.ZERO;

        for (int i = 0; i < drugVolumeList.size(); i++) {
            if (i < 9) {
                top9List.add(drugVolumeList.get(i));
            } else {
                // 累加其他药品的销售额
                otherTotalAmount = otherTotalAmount.add(drugVolumeList.get(i).getSaleVolume());
            }
        }

        // 如果有其他药品，添加“其他”类别
        if (otherTotalAmount.compareTo(BigDecimal.ZERO) > 0) {
            DrugVolumeVo otherVo = new DrugVolumeVo();
            otherVo.setMedicineName("其他");
            otherVo.setSaleVolume(otherTotalAmount);
            top9List.add(otherVo);
        }

        return top9List;
    }

    /**
     * 获取一段时间每天的销售额
     */
    @ApiOperation("获取一段时间每天的销售额")
    @GetMapping("/SalesVolume")
    public List<SalesVolumeVo> getSalesVolume() {
        List<SalesRecord> salesRecordList = salesRecordService.selectSalesRecordListByStatus(null);
        List<SalesVolumeVo> salesVolumeVoList = new ArrayList<>();
        // 获取本地时间
        Date nowDate = DateUtils.getNowDate();
        // 为salesVolumeVoList设置7天的时间
        for (int i = 0; i < 7; i++) {
            SalesVolumeVo salesVolumeVo = new SalesVolumeVo();
            salesVolumeVo.setSaleDate(DateUtils.addDays(nowDate, -i));
            // 设置销售额（0）
            salesVolumeVo.setTotalAmount(new java.math.BigDecimal(0));
            salesVolumeVoList.add(salesVolumeVo);
        }
        for (SalesRecord salesRecord : salesRecordList) {
            // 遍历 salesVolumeVoList，查找是否存在相同的日期
            for (SalesVolumeVo salesVolumeVo : salesVolumeVoList) {
                LocalDate saleDate = salesRecord.getSaleDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                LocalDate voDate = salesVolumeVo.getSaleDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                if (voDate.equals(saleDate)) {
                    // 如果找到匹配的日期，累加金额
                    salesVolumeVo.setTotalAmount(salesVolumeVo.getTotalAmount().add(salesRecord.getTotalAmount()));
                    break;
                }
            }
        }
        //按日期升序
        salesVolumeVoList.sort(Comparator.comparing(SalesVolumeVo::getSaleDate));
        //降序
        //salesVolumeVoList.sort(Comparator.comparing(SalesVolumeVo::getSaleDate).reversed());
        return salesVolumeVoList;
    }

    /**
     * 获取销售排行前十
     */
    @ApiOperation("获取销售排行前十")
    @GetMapping("/TopTen")
    public TableDataInfo getTopTen() {
        List<SalesRecord> salesRecordList = salesRecordService.selectSalesRecordListByStatus(null);
        List<TopTenVo> topTenVoLists = new ArrayList<>();
        // 初始化 topTenVoLists 并设置 MedicineName
        for (SalesRecord salesRecord : salesRecordList) {
            // 查看topTenVoLists 中是否存在该药品，如果存在，则数量加一，如果不存在，则添加
            if (topTenVoLists.size() == 0) {
                TopTenVo topTenVo = new TopTenVo();
                topTenVo.setMedicineName(salesRecord.getMedicineName());
                topTenVo.setCount(1L);
                topTenVoLists.add(topTenVo);
                continue;
            }
            for (int i = 0; i < topTenVoLists.size(); i++) {
                if (topTenVoLists.get(i).getMedicineName().equals(salesRecord.getMedicineName())) {
                    topTenVoLists.get(i).setCount(topTenVoLists.get(i).getCount() + 1);
                    break;
                }
                //如果循环结束，说明该药品不存在，则添加
                if (i == topTenVoLists.size() - 1) {
                    TopTenVo topTenVo = new TopTenVo();
                    topTenVo.setMedicineName(salesRecord.getMedicineName());
                    topTenVo.setCount(1L);
                    topTenVoLists.add(topTenVo);
                    break;
                }
            }
            if (topTenVoLists.size() == 10) {
                break;
            }
        }
        // 对 topTenVoLists 进行排序(升序)
        Collections.sort(topTenVoLists, (o1, o2) -> o2.getCount().compareTo(o1.getCount()));
        return getDataTable(topTenVoLists);
    }

    /**
     * 获取订单数量和订单金额
     */
    @ApiOperation("获取订单数量和订单金额")
    @GetMapping("/OrderAndVolume")
    public AjaxResult getOrderAndVolume() {
        SalesRecordVo salesRecordVo = new SalesRecordVo();
        List<SalesRecord> lists = salesRecordService.selectSalesRecordList(null);
        // 获取本地时间
        Date nowDate = DateUtils.getNowDate();
        for (SalesRecord list : lists) {
            // 判断时间是否在9天内
            if (DateUtils.differentDaysByMillisecond(list.getSaleDate(), nowDate) <= 10) {
                salesRecordVo.setOrderNum(salesRecordVo.getOrderNum() + 1);
                if (list.getStatus().equals("1")) {
                    salesRecordVo.setOrderCountNum(salesRecordVo.getOrderCountNum() + 1);
                    salesRecordVo.setOrderAmountNum(salesRecordVo.getOrderAmountNum().add(list.getTotalAmount()));
                } else if (list.getStatus().equals("2")) {
                    salesRecordVo.setOrderHangNum(salesRecordVo.getOrderHangNum() + 1);
                } else if (list.getStatus().equals("3")) {
                    salesRecordVo.setOrderReturnNum(salesRecordVo.getOrderReturnNum() + 1);
                }
            }
        }
        return success(salesRecordVo);
    }

    /**
     * 查询药品销售记录列表
     */
    @ApiOperation("查询药品销售记录列表")
    @PreAuthorize("@ss.hasPermi('manage:record:list')")
    @GetMapping("/list")
    public TableDataInfo list(SalesRecord salesRecord)
    {
        startPage();
        List<SalesRecord> list = salesRecordService.selectSalesRecordList(salesRecord);
        return getDataTable(list);
    }

    /**
     * 导出药品销售记录列表
     */
    @ApiOperation("导出药品销售记录列表")
    @PreAuthorize("@ss.hasPermi('manage:record:export')")
    @Log(title = "药品销售记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SalesRecord salesRecord)
    {
        List<SalesRecord> list = salesRecordService.selectSalesRecordList(salesRecord);
        ExcelUtil<SalesRecord> util = new ExcelUtil<SalesRecord>(SalesRecord.class);
        util.exportExcel(response, list, "药品销售记录数据");
    }

    /**
     * 获取药品销售记录详细信息
     */
    @ApiOperation("获取药品销售记录详细信息")
    @PreAuthorize("@ss.hasPermi('manage:record:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(salesRecordService.selectSalesRecordById(id));
    }

    /**
     * 新增药品销售记录
     */
    @ApiOperation("新增药品销售记录")
    @PreAuthorize("@ss.hasPermi('manage:record:add')")
    @Log(title = "药品销售记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SalesRecord salesRecord)
    {
        return toAjax(salesRecordService.insertSalesRecord(salesRecord));
    }

    /**
     * 修改药品销售记录
     */
    @ApiOperation("修改药品销售记录")
    @PreAuthorize("@ss.hasPermi('manage:record:edit')")
    @Log(title = "药品销售记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Sales sales)
    {
        //如果状态为退单，则修改药品库存数量
        if (sales.getStatus().equals("3")) {
            //修改药品库存数量
            medicinesService.updateStockQuantityAdd(sales.getMedicineCode(), sales.getBatchNumber(), sales.getQuantity());
        }
        return toAjax(salesRecordService.updateSalesRecord(sales));
    }

    /**
     * 删除药品销售记录
     */
    @ApiOperation("删除药品销售记录")
    @PreAuthorize("@ss.hasPermi('manage:record:remove')")
    @Log(title = "药品销售记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(salesRecordService.deleteSalesRecordByIds(ids));
    }
}